Sensor Fusion for Kinetis MCUs (ISSDK/KSDK version)
sensor_fusion.c File Reference
+ Include dependency graph for sensor_fusion.c:

Go to the source code of this file.

Functions

void setStatus (SensorFusionGlobals *sfg, fusion_status_t status)
 
void queueStatus (SensorFusionGlobals *sfg, fusion_status_t status)
 
void updateStatus (SensorFusionGlobals *sfg)
 
void testStatus (SensorFusionGlobals *sfg)
 
void initSensorFusionGlobals (SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
 
int8_t installSensor (SensorFusionGlobals *sfg, PhysicalSensor *pSensor, uint16_t addr, uint16_t schedule, void *bus_driver, initializeSensor_t *initialize, readSensor_t *read)
 
int8_t initializeSensors (SensorFusionGlobals *sfg)
 
void processMagData (SensorFusionGlobals *sfg)
 
int8_t readSensors (SensorFusionGlobals *sfg, uint16_t read_loop_counter)
 
void conditionSensorReadings (SensorFusionGlobals *sfg)
 
void zeroArray (StatusSubsystem *pStatus, void *data, uint16_t size, uint16_t numElements, uint8_t check)
 
void clearFIFOs (SensorFusionGlobals *sfg)
 
void runFusion (SensorFusionGlobals *sfg)
 
void initializeFusionEngine (SensorFusionGlobals *sfg)
 
void conditionSample (int16_t sample[3])
 
void addToFifo (FifoSensor *sensor, uint16_t maxFifoSize, int16_t sample[3])
 

Function Documentation

void addToFifo ( FifoSensor sensor,
uint16_t  maxFifoSize,
int16_t  sample[3] 
)

addToFifo is called from within sensor driver read functions

addToFifo is called from within sensor driver read functions to transfer new readings into the sensor structure corresponding to accel, gyro or mag. This function ensures that the software FIFOs are not overrun.

example usage: if (status==SENSOR_ERROR_NONE) addToFifo((FifoSensor*) &(sfg->Mag), MAG_FIFO_SIZE, sample);

Parameters
sensorpointer to structure of type AccelSensor, MagSensor or GyroSensor
maxFifoSizethe size of the software (not hardware) FIFO
samplethe sample to add

Definition at line 531 of file sensor_fusion.c.

Referenced by FXLS8471Q_Read(), FXOS8700_Init(), FXOS8700_ReadMagData(), and MAG3110_Read().

532 {
533  // Note that FifoSensor is a union of GyroSensor, MagSensor and AccelSensor.
534  // All contain FIFO structures in the same location. We use the Accel
535  // structure to index here.
536 
537  // example usage: if (status==SENSOR_ERROR_NONE) addToFifo((FifoSensor*) &(sfg->Mag), MAG_FIFO_SIZE, sample);
538  uint8_t fifoCount = sensor->Accel.iFIFOCount;
539  if (fifoCount < maxFifoSize) {
540  // we have room for the new sample
541  sensor->Accel.iGsFIFO[fifoCount][CHX] = sample[CHX];
542  sensor->Accel.iGsFIFO[fifoCount][CHY] = sample[CHY];
543  sensor->Accel.iGsFIFO[fifoCount][CHZ] = sample[CHZ];
544  sensor->Accel.iFIFOCount += 1;
545  sensor->Accel.iFIFOExceeded = 0;
546  } else {
547  //there is no room for a new sample
548  sensor->Accel.iFIFOExceeded += 1;
549  }
550 }
int16_t iGsFIFO[ACCEL_FIFO_SIZE][3]
FIFO measurements (counts)
#define CHY
Used to access Y-channel entries in various data data structures.
Definition: sensor_fusion.h:77
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
AccelSensor Accel
#define CHZ
#define CHX
Used to access X-channel entries in various data data structures.
Definition: sensor_fusion.h:76
uint8_t iFIFOCount
number of measurements read from FIFO

+ Here is the caller graph for this function:

void clearFIFOs ( SensorFusionGlobals sfg)

Function to clear FIFO at the end of each fusion computation.

Parameters
sfgGlobal data structure pointer

Definition at line 363 of file sensor_fusion.c.

Referenced by initializeFusionEngine(), initSensorFusionGlobals(), and runFusion().

363  {
364  // We only clear FIFOs if the sensors are enabled. This allows us
365  // to continue to use these values when we've shut higher power consumption
366  // sensors down during periods of no activity.
367 #if F_USING_ACCEL
368  sfg->Accel.iFIFOCount=0;
369  sfg->Accel.iFIFOExceeded = false;
370 #endif
371 #if F_USING_MAG
372  sfg->Mag.iFIFOCount=0;
373  sfg->Mag.iFIFOExceeded = false;
374 #endif
375 #if F_USING_GYRO
376  sfg->Gyro.iFIFOCount=0;
377  sfg->Gyro.iFIFOExceeded = false;
378 #endif
379 }
MagSensor Mag
magnetometer storage
uint8_t iFIFOCount
number of measurements read from FIFO
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.

+ Here is the caller graph for this function:

void conditionSample ( int16_t  sample[3])

conditionSample ensures that we never encounter the maximum negative two's complement value for a 16-bit variable (-32768).

conditionSample ensures that we never encounter the maximum negative two's complement value for a 16-bit variable (-32768). This value cannot be negated, because the maximum positive value is +32767. We need the ability to negate to gaurantee that subsequent HAL operations can be run successfully.

Parameters
sample16-bit register value from triaxial sensor read

Definition at line 519 of file sensor_fusion.c.

Referenced by FXLS8471Q_Read(), FXOS8700_Init(), FXOS8700_ReadMagData(), and MAG3110_Read().

520 {
521  // This function should be called for every 16 bit sample read from sensor hardware.
522  // It is responsible for making sure that we never pass on the value of -32768.
523  // That value cannot be properly negated using 16-bit twos complement math.
524  // The ability to be later negated is required for general compatibility
525  // with possible HAL (Hardware abstraction logic) which is run later in
526  // the processing pipeline.
527  if (sample[CHX] == -32768) sample[CHX]++;
528  if (sample[CHY] == -32768) sample[CHY]++;
529  if (sample[CHZ] == -32768) sample[CHZ]++;
530 }
#define CHY
Used to access Y-channel entries in various data data structures.
Definition: sensor_fusion.h:77
#define CHZ
#define CHX
Used to access X-channel entries in various data data structures.
Definition: sensor_fusion.h:76

+ Here is the caller graph for this function:

void conditionSensorReadings ( SensorFusionGlobals sfg)

conditionSensorReadings() transforms raw software FIFO readings into forms that can be consumed by the sensor fusion engine. This include sample averaging and (in the case of the gyro) integrations, applying hardware abstraction layers, and calibration functions. This function is normally involved via the "sfg." global pointer.

Parameters
sfgGlobal data structure pointer

Definition at line 305 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

305  {
306 #if F_USING_ACCEL
307  if (sfg->Accel.isEnabled) processAccelData(sfg);
308 #endif
309 
310 #if F_USING_MAG
311  if (sfg->Mag.isEnabled) processMagData(sfg);
312 #endif
313 
314 #if F_USING_GYRO
315  if (sfg->Gyro.isEnabled) processGyroData(sfg);
316 #endif
317  return;
318 }
void processMagData(SensorFusionGlobals *sfg)
MagSensor Mag
magnetometer storage
bool isEnabled
true if the device is sampling

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void initializeFusionEngine ( SensorFusionGlobals sfg)

This function is responsible for initializing the system prior to starting the main fusion loop. This function is normally involved via the "sfg." global pointer.

Definition at line 471 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

472 {
473  int16_t status = 0;
474  ControlSubsystem *pComm;
475  pComm = sfg->pControlSubsystem;
476 
477  // configure the 24 bit downwards ARM systick timer and wait 50ms=CORE_SYSTICK_HZ / 20 clock ticks
478  // to avoid a race condition between Kinetis and the sensors after power on.
480  // wait 50ms to avoid a race condition with sensors at power on
481  ARM_systick_delay_ms(CORE_SYSTICK_HZ, 50);
482 
483  sfg->setStatus(sfg, INITIALIZING);
484  status = initializeSensors(sfg);
485  if (status!=SENSOR_ERROR_NONE) { // fault condition found
486  sfg->setStatus(sfg, HARD_FAULT); // Never returns
487  }
488 
489  // recall: typedef enum quaternion {Q3, Q3M, Q3G, Q6MA, Q6AG, Q9} quaternion_type;
490  // Set the default quaternion to the most sophisticated supported by this build
498 
499  // initialize the sensor fusion algorithms
500  fInitializeFusion(sfg);
501 
502  // reset the loop counter to zero for first iteration
503  sfg->loopcounter = 0;
504 
505  // initialize the magnetic calibration and magnetometer data buffer
506 #if F_USING_MAG
508 #endif
509 
510  // initialize the precision accelerometer calibration and accelerometer data buffer
511 #if F_USING_ACCEL
512  fInitializeAccelCalibration(&sfg->AccelCal, &sfg->AccelBuffer, &sfg->pControlSubsystem->AccelCalPacketOn );
513 #endif
514  sfg->setStatus(sfg, NORMAL);
515 
516  clearFIFOs(sfg);
517 }
void ARM_systick_enable(void)
Initializing sensors and algorithms.
Quaternion derived from full 9-axis sensor fusion.
Definition: sensor_fusion.h:70
void fInitializeFusion(SensorFusionGlobals *sfg)
Definition: fusion.c:51
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
void fInitializeMagCalibration(MagCalibration *pthisMagCal, MagBuffer *pthisMagBuffer)
Definition: magnetic.c:41
uint32_t iFlags
a bit-field of sensors and algorithms used
Quaternion derived from 3-axis mag only (auto compass algorithm)
Definition: sensor_fusion.h:66
MagCalibration MagCal
mag cal storage
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
Definition: control.h:71
Quaternion derived from 3-axis gyro only (rotation)
Definition: sensor_fusion.h:67
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
Definition: sensor_fusion.h:68
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
Definition: control.h:65
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
Definition: sensor_fusion.h:69
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
struct ControlSubsystem * pControlSubsystem
#define F_9DOF_GBY_KALMAN
#define F_6DOF_GY_KALMAN
6DOF accel and gyro (Kalman) algorithm selector - 0x2000 to include, 0x0000 otherwise ...
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:64
MagBuffer MagBuffer
mag cal constellation points
Non-recoverable FAULT = something went very wrong.
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:65
#define F_3DOF_Y_BASIC
3DOF gyro integration algorithm selector - 0x0800 to include, 0x0000 otherwise
#define F_6DOF_GB_BASIC
6DOF accel and mag eCompass algorithm selector - 0x1000 to include, 0x0000 otherwise ...
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
void ARM_systick_delay_ms(uint32 iSystemCoreClock, uint32 delay_ms)
setStatus_t * setStatus
change status indicator immediately
Operation is Nominal.
#define F_3DOF_B_BASIC
3DOF mag eCompass (vehicle/mag) algorithm selector - 0x0400 to include, 0x0000 otherwise ...
int8_t initializeSensors(SensorFusionGlobals *sfg)
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
Definition: control.h:66

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int8_t initializeSensors ( SensorFusionGlobals sfg)

Definition at line 157 of file sensor_fusion.c.

Referenced by initializeFusionEngine().

158 {
159  PhysicalSensor *pSensor;
160  int8_t s;
161  int8_t status = 0;
162  for (pSensor = sfg->pSensors; pSensor != NULL; pSensor = pSensor->next)
163  {
164  s = pSensor->initialize(pSensor, sfg);
165  if (status == 0) status = s; // will return 1st error flag, but try all sensors
166  }
167  return (status);
168 }
struct PhysicalSensor * next
pointer to next sensor in this linked list
initializeSensor_t * initialize
pointer to function to initialize sensor using the supplied drivers
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
PhysicalSensor * pSensors
a linked list of physical sensors

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void initSensorFusionGlobals ( SensorFusionGlobals sfg,
StatusSubsystem pStatusSubsystem,
ControlSubsystem pControlSubsystem 
)

utility function to insert default values in the top level structure

Parameters
sfgGlobal data structure pointer
pStatusSubsystemStatus subsystem pointer
pControlSubsystemControl subsystem pointer

Definition at line 68 of file sensor_fusion.c.

Referenced by main().

71 {
72  sfg->iFlags = // all of the following defines are either 0x0000 or a 1-bit value (2, 4, 8 ...) and are defined in build.h
74  F_USING_MAG |
75  F_USING_GYRO |
78  F_ALL_SENSORS | // refers to all applicable sensor types for the given physical unit
79  F_1DOF_P_BASIC | // 1DOF pressure (altitude) and temperature: (pressure)
80  F_3DOF_G_BASIC | // 3DOF accel tilt: (accel)
81  F_3DOF_B_BASIC | // 3DOF mag eCompass (vehicle): (mag)
82  F_3DOF_Y_BASIC | // 3DOF gyro integration: (gyro)
83  F_6DOF_GB_BASIC | // 6DOF accel and mag eCompass)
84  F_6DOF_GY_KALMAN | // 6DOF accel and gyro (Kalman): (accel + gyro)
85  F_9DOF_GBY_KALMAN ; // 9DOF accel, mag and gyro (Kalman): (accel + mag + gyro)
86 
87  sfg->pControlSubsystem = pControlSubsystem;
88  sfg->pStatusSubsystem = pStatusSubsystem;
89  sfg->loopcounter = 0; // counter incrementing each iteration of sensor fusion (typically 25Hz)
90  sfg->systick_I2C = 0; // systick counter to benchmark I2C reads
91  sfg->systick_Spare = 0; // systick counter for counts spare waiting for timing interrupt
92  sfg->iPerturbation = 0; // no perturbation to be applied
93  sfg->installSensor = installSensor; // function for installing a new sensor into the structures
94  sfg->initializeFusionEngine = initializeFusionEngine; // function for installing a new sensor into the structures
95  sfg->readSensors = readSensors; // function for installing a new sensor into the structures
96  sfg->runFusion = runFusion; // function for installing a new sensor into the structures
97  sfg->applyPerturbation = ApplyPerturbation; // function used for step function testing
98  sfg->conditionSensorReadings = conditionSensorReadings; // function does averaging, HAL adjustments, etc.
99  sfg->clearFIFOs = clearFIFOs; // function to clear FIFO flags sfg->applyPerturbation = ApplyPerturbation; // function used for step function testing
100  sfg->setStatus = setStatus; // function to immediately set status change
101  sfg->queueStatus = queueStatus; // function to queue status change
102  sfg->updateStatus = updateStatus; // function to promote queued status change
103  sfg->testStatus = testStatus; // function for unit testing the status subsystem
104  sfg->pSensors = NULL; // pointer to linked list of physical sensors
105 // put error value into whoAmI as initial value
106 #if F_USING_ACCEL
107  sfg->Accel.iWhoAmI = 0;
108 #endif
109 #if F_USING_MAG
110  sfg->Mag.iWhoAmI = 0;
111 #endif
112 #if F_USING_GYRO
113  sfg->Gyro.iWhoAmI = 0;
114 #endif
115 #if F_USING_PRESSURE
116  sfg->Pressure.iWhoAmI = 0;
117 #endif
118 }
#define F_USING_GYRO
nominally 0x0004 if a gyro is to be used, 0x0000 otherwise
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
clearFIFOs_t * clearFIFOs
clear sensor FIFOs
int32_t systick_I2C
systick counter to benchmark I2C reads
#define F_ALL_SENSORS
uint32_t iFlags
a bit-field of sensors and algorithms used
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
void setStatus(SensorFusionGlobals *sfg, fusion_status_t status)
Poor man&#39;s inheritance for status subsystem setStatus command This function is normally involved via ...
Definition: sensor_fusion.c:43
#define F_USING_PRESSURE
nominally 0x0008 if altimeter is to be used, 0x0000 otherwise
installSensor_t * installSensor
function for installing a new sensor into t
int8_t installSensor(SensorFusionGlobals *sfg, PhysicalSensor *pSensor, uint16_t addr, uint16_t schedule, void *bus_driver, initializeSensor_t *initialize, readSensor_t *read)
installSensor is used to instantiate a physical sensor driver into the sensor fusion system...
void testStatus(SensorFusionGlobals *sfg)
Definition: sensor_fusion.c:62
void initializeFusionEngine(SensorFusionGlobals *sfg)
This function is responsible for initializing the system prior to starting the main fusion loop...
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
readSensors_t * readSensors
read all physical sensors
struct ControlSubsystem * pControlSubsystem
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
MagSensor Mag
magnetometer storage
#define F_1DOF_P_BASIC
1DOF pressure (altitude) and temperature algorithm selector - 0x0100 to include, 0x0000 otherwise ...
#define F_9DOF_GBY_KALMAN
updateStatus_t * updateStatus
status=next status
int8_t readSensors(SensorFusionGlobals *sfg, uint16_t read_loop_counter)
readSensors traverses the linked list of physical sensors, calling the individual read functions one ...
#define F_6DOF_GY_KALMAN
6DOF accel and gyro (Kalman) algorithm selector - 0x2000 to include, 0x0000 otherwise ...
void runFusion(SensorFusionGlobals *sfg)
runFusion the top level call that actually runs the sensor fusion. This is a utility function which m...
#define F_3DOF_G_BASIC
3DOF accel tilt (accel) algorithm selector - 0x0200 to include, 0x0000 otherwise
void queueStatus(SensorFusionGlobals *sfg, fusion_status_t status)
Poor man&#39;s inheritance for status subsystem queueStatus command. This function is normally involved v...
Definition: sensor_fusion.c:50
#define F_USING_TEMPERATURE
nominally 0x0010 if temp sensor is to be used, 0x0000 otherwise
runFusion_t * runFusion
run the fusion routines
struct StatusSubsystem * pStatusSubsystem
void conditionSensorReadings(SensorFusionGlobals *sfg)
conditionSensorReadings() transforms raw software FIFO readings into forms that can be consumed by th...
uint8_t iWhoAmI
sensor whoami
void updateStatus(SensorFusionGlobals *sfg)
Poor man&#39;s inheritance for status subsystem updateStatus command. This function is normally involved ...
Definition: sensor_fusion.c:57
#define F_3DOF_Y_BASIC
3DOF gyro integration algorithm selector - 0x0800 to include, 0x0000 otherwise
setStatus_t * queueStatus
queue status change for next regular interval
#define F_6DOF_GB_BASIC
6DOF accel and mag eCompass algorithm selector - 0x1000 to include, 0x0000 otherwise ...
#define F_USING_ACCEL
nominally 0x0001 if an accelerometer is to be used, 0x0000 otherwise
setStatus_t * setStatus
change status indicator immediately
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
#define F_3DOF_B_BASIC
3DOF mag eCompass (vehicle/mag) algorithm selector - 0x0400 to include, 0x0000 otherwise ...
#define F_USING_MAG
Definition: magnetic.h:38
volatile uint8_t iPerturbation
test perturbation to be applied
applyPerturbation_t ApplyPerturbation
ApplyPerturbation is a reverse unit-step test function.
PhysicalSensor * pSensors
a linked list of physical sensors

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int8_t installSensor ( SensorFusionGlobals sfg,
PhysicalSensor pSensor,
uint16_t  addr,
uint16_t  schedule,
void *  bus_driver,
initializeSensor_t initialize,
readSensor_t read 
)

installSensor is used to instantiate a physical sensor driver into the sensor fusion system. This function is normally involved via the "sfg." global pointer.

Parameters
sfgtop level fusion structure
pSensorpointer to structure describing physical sensor
addrI2C address for sensor (if applicable)
scheduleParameter to control sensor sampling rate
bus_driverISSDK sensor bus driver (usually KSDK I2C bus)
initializepointer to sensor initialization function
readpointer to sensor read function

Definition at line 122 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

130 {
131  if (sfg && pSensor && bus_driver && initialize && read)
132  {
133  pSensor->bus_driver = bus_driver;
134  pSensor->initialize = initialize; // The initialization function is responsible for putting the sensor
135  // into the proper mode for sensor fusion. It is normally KSDK-based.
136  pSensor->read = read; // The read function is responsible for taking sensor readings and
137  // loading them into the sensor fusion input structures. Also KDSK-based.
138  pSensor->addr = addr; // I2C address if applicable
139  pSensor->schedule = schedule;
140  pSensor->slaveParams.pReadPreprocessFN = NULL; // SPI-specific parameters get overwritten later if used
141  pSensor->slaveParams.pWritePreprocessFN = NULL;
142  pSensor->slaveParams.pTargetSlavePinID = NULL;
143  pSensor->slaveParams.spiCmdLen = 0;
144  pSensor->slaveParams.ssActiveValue = 0;
145  // Now add the new sensor at the head of the linked list
146  pSensor->next = sfg->pSensors;
147  sfg->pSensors = pSensor;
148  return (0);
149  }
150  else
151  {
152  return (1);
153  }
154 }
void * bus_driver
should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) ...
readSensor_t * read
pointer to function to read sensor using the supplied drivers
uint16_t schedule
Parameter to control sensor sampling rate.
struct PhysicalSensor * next
pointer to next sensor in this linked list
initializeSensor_t * initialize
pointer to function to initialize sensor using the supplied drivers
spiSlaveSpecificParams_t slaveParams
SPI specific parameters. Not used for I2C.
uint16_t addr
I2C address if applicable.
PhysicalSensor * pSensors
a linked list of physical sensors

+ Here is the caller graph for this function:

void processMagData ( SensorFusionGlobals sfg)

Definition at line 209 of file sensor_fusion.c.

Referenced by conditionSensorReadings().

210 {
211  int32 iSum[3]; // channel sums
212  int16 i, j; // counters
213 
214  // printf("ProcessingMagData()\n");
215  if (sfg->Mag.iFIFOExceeded > 0) {
216  sfg->setStatus(sfg, SOFT_FAULT);
217  }
218 
219  ApplyMagHAL(&(sfg->Mag)); // This function is board-dependent
220 
221  // calculate the average HAL-corrected measurement
222  for (j = CHX; j <= CHZ; j++) iSum[j] = 0;
223  for (i = 0; i < sfg->Mag.iFIFOCount; i++)
224  for (j = CHX; j <= CHZ; j++) iSum[j] += sfg->Mag.iBsFIFO[i][j];
225  if (sfg->Mag.iFIFOCount > 0)
226  {
227  for (j = CHX; j <= CHZ; j++)
228  {
229  sfg->Mag.iBs[j] = (int16)(iSum[j] / (int32) sfg->Mag.iFIFOCount);
230  sfg->Mag.fBs[j] = (float)sfg->Mag.iBs[j] * sfg->Mag.fuTPerCount;
231  }
232  }
233 
234  // remove hard and soft iron terms from fBs (uT) to get calibrated data fBc (uT), iBc (counts) and
235  // update magnetic buffer avoiding a write while a magnetic calibration is in progress.
236  // run one iteration of the time sliced magnetic calibration
237  fInvertMagCal(&(sfg->Mag), &(sfg->MagCal));
238  if (!sfg->MagCal.iMagBufferReadOnly)
239  iUpdateMagBuffer(&(sfg->MagBuffer), &(sfg->Mag), sfg->loopcounter);
240  fRunMagCalibration(&(sfg->MagCal), &(sfg->MagBuffer), &(sfg->Mag),
241  sfg->loopcounter);
242 
243  return;
244 }
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
int16_t iBs[3]
averaged uncalibrated measurement (counts)
MagCalibration MagCal
mag cal storage
void iUpdateMagBuffer(MagBuffer *pthisMagBuffer, MagSensor *pthisMag, int32 loopcounter)
Definition: magnetic.c:103
void fInvertMagCal(MagSensor *pthisMag, MagCalibration *pthisMagCal)
Definition: magnetic.c:297
int32_t int32
Definition: sensor_fusion.h:57
MagSensor Mag
magnetometer storage
Recoverable FAULT = something went wrong, but we can keep going.
int8_t iMagBufferReadOnly
flag to denote that the magnetic measurement buffer is temporarily read only
Definition: magnetic.h:100
float fuTPerCount
uT per count
#define CHZ
void fRunMagCalibration(MagCalibration *pthisMagCal, MagBuffer *pthisMagBuffer, MagSensor *pthisMag, int32 loopcounter)
Definition: magnetic.c:325
uint8_t iFIFOCount
number of measurements read from FIFO
#define CHX
Used to access X-channel entries in various data data structures.
Definition: sensor_fusion.h:76
MagBuffer MagBuffer
mag cal constellation points
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
float fBs[3]
averaged un-calibrated measurement (uT)
int16_t iBsFIFO[MAG_FIFO_SIZE][3]
FIFO measurements (counts)
setStatus_t * setStatus
change status indicator immediately
int16_t int16
Definition: sensor_fusion.h:56
void ApplyMagHAL(MagSensor *Mag)
Apply the magnetometer Hardware Abstraction Layer.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void queueStatus ( SensorFusionGlobals sfg,
fusion_status_t  status 
)

Poor man's inheritance for status subsystem queueStatus command. This function is normally involved via the "sfg." global pointer.

Definition at line 50 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

51 {
52  sfg->pStatusSubsystem->queue(sfg->pStatusSubsystem, status);
53 }
struct StatusSubsystem * pStatusSubsystem
ssSetStatus_t * queue
queue status change for next regular interval
Definition: status.h:51

+ Here is the caller graph for this function:

int8_t readSensors ( SensorFusionGlobals sfg,
uint16_t  read_loop_counter 
)

readSensors traverses the linked list of physical sensors, calling the individual read functions one by one. This function is normally involved via the "sfg." global pointer.

Parameters
sfgpointer to global sensor fusion data structure
read_loop_countercurrent loop counter (used for multirate processing)

Definition at line 276 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

280 {
281  PhysicalSensor *pSensor;
282  int8_t s;
283  int8_t status = 0;
284  float remainder;
285 
286  pSensor = sfg->pSensors;
287 
288  for (pSensor = sfg->pSensors; pSensor != NULL; pSensor = pSensor->next)
289  { if (pSensor->isInitialized) {
290  remainder = fmod(read_loop_counter, pSensor->schedule);
291  if (remainder==0) {
292  s = pSensor->read(pSensor, sfg);
293  if (status == 0) status = s; // will return 1st error flag, but try all sensors
294  }
295  }
296  }
297  if (status==SENSOR_ERROR_INIT) sfg->setStatus(sfg, HARD_FAULT); // Never returns
298  return (status);
299 }
readSensor_t * read
pointer to function to read sensor using the supplied drivers
uint16_t schedule
Parameter to control sensor sampling rate.
struct PhysicalSensor * next
pointer to next sensor in this linked list
Non-recoverable FAULT = something went very wrong.
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
uint16_t isInitialized
Bitfields to indicate sensor is active (use SensorBitFields from build.h)
setStatus_t * setStatus
change status indicator immediately
PhysicalSensor * pSensors
a linked list of physical sensors

+ Here is the caller graph for this function:

void runFusion ( SensorFusionGlobals sfg)

runFusion the top level call that actually runs the sensor fusion. This is a utility function which manages the various defines in build.h. You should feel free to drop down a level and implement only those portions of fFuseSensors() that your application needs. This function is normally involved via the "sfg." global pointer.

Definition at line 386 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

387 {
388  struct SV_1DOF_P_BASIC *pSV_1DOF_P_BASIC;
389  struct SV_3DOF_G_BASIC *pSV_3DOF_G_BASIC;
390  struct SV_3DOF_B_BASIC *pSV_3DOF_B_BASIC;
391  struct SV_3DOF_Y_BASIC *pSV_3DOF_Y_BASIC;
392  struct SV_6DOF_GB_BASIC *pSV_6DOF_GB_BASIC;
393  struct SV_6DOF_GY_KALMAN *pSV_6DOF_GY_KALMAN;
394  struct SV_9DOF_GBY_KALMAN *pSV_9DOF_GBY_KALMAN;
395  struct AccelSensor *pAccel;
396  struct MagSensor *pMag;
397  struct GyroSensor *pGyro;
398  struct PressureSensor *pPressure;
399  struct MagCalibration *pMagCal;
400 #if F_1DOF_P_BASIC
401  pSV_1DOF_P_BASIC = &(sfg->SV_1DOF_P_BASIC);
402 #else
403  pSV_1DOF_P_BASIC = NULL;
404 #endif
405 #if F_3DOF_G_BASIC
406  pSV_3DOF_G_BASIC = &(sfg->SV_3DOF_G_BASIC) ;
407 #else
408  pSV_3DOF_G_BASIC = NULL;
409 #endif
410 #if F_3DOF_B_BASIC
411  pSV_3DOF_B_BASIC = &(sfg->SV_3DOF_B_BASIC);
412 #else
413  pSV_3DOF_B_BASIC = NULL;
414 #endif
415 #if F_3DOF_Y_BASIC
416  pSV_3DOF_Y_BASIC = &(sfg->SV_3DOF_Y_BASIC);
417 #else
418  pSV_3DOF_Y_BASIC = NULL;
419 #endif
420 #if F_6DOF_GB_BASIC
421  pSV_6DOF_GB_BASIC = &(sfg->SV_6DOF_GB_BASIC);
422 #else
423  pSV_6DOF_GB_BASIC = NULL;
424 #endif
425 #if F_6DOF_GY_KALMAN
426  pSV_6DOF_GY_KALMAN = &(sfg->SV_6DOF_GY_KALMAN);
427 #else
428  pSV_6DOF_GY_KALMAN = NULL;
429 #endif
430 #if F_9DOF_GBY_KALMAN
431  pSV_9DOF_GBY_KALMAN = &(sfg->SV_9DOF_GBY_KALMAN);
432 #else
433  pSV_9DOF_GBY_KALMAN = NULL;
434 #endif
435 #if F_USING_ACCEL
436  pAccel = &(sfg->Accel);
437 #else
438  pAccel = NULL;
439 #endif
440 #if F_USING_MAG
441  pMag = &(sfg->Mag);
442  pMagCal = &(sfg->MagCal);
443 #else
444  pMag = NULL;
445  pMagCal = NULL;
446 #endif
447 #if F_USING_GYRO
448  pGyro = &(sfg->Gyro);
449 #else
450  pGyro = NULL;
451 #endif
452 #if F_USING_PRESSURE
453  pPressure = &(sfg->Pressure);
454 #else
455  pPressure = NULL;
456 #endif
457 
458  // conditionSensorReadings(sfg); must be called prior to this function
459  // fuse the sensor data
460  fFuseSensors(pSV_1DOF_P_BASIC, pSV_3DOF_G_BASIC,
461  pSV_3DOF_B_BASIC, pSV_3DOF_Y_BASIC,
462  pSV_6DOF_GB_BASIC, pSV_6DOF_GY_KALMAN,
463  pSV_9DOF_GBY_KALMAN, pAccel, pMag, pGyro,
464  pPressure, pMagCal);
465  clearFIFOs(sfg);
466 }
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
MagCalibration MagCal
mag cal storage
This is the 3DOF basic accelerometer state vector structure.
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
Magnetic Calibration Structure.
Definition: magnetic.h:72
MagSensor Mag
magnetometer storage
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
This is the 3DOF basic magnetometer state vector structure/.
The PressureSensor structure stores raw and processed measurements for an altimeter.
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
void fFuseSensors(struct SV_1DOF_P_BASIC *pthisSV_1DOF_P_BASIC, struct SV_3DOF_G_BASIC *pthisSV_3DOF_G_BASIC, struct SV_3DOF_B_BASIC *pthisSV_3DOF_B_BASIC, struct SV_3DOF_Y_BASIC *pthisSV_3DOF_Y_BASIC, struct SV_6DOF_GB_BASIC *pthisSV_6DOF_GB_BASIC, struct SV_6DOF_GY_KALMAN *pthisSV_6DOF_GY_KALMAN, struct SV_9DOF_GBY_KALMAN *pthisSV_9DOF_GBY_KALMAN, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, struct GyroSensor *pthisGyro, struct PressureSensor *pthisPressure, struct MagCalibration *pthisMagCal)
Definition: fusion.c:86
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void setStatus ( SensorFusionGlobals sfg,
fusion_status_t  status 
)

Poor man's inheritance for status subsystem setStatus command This function is normally involved via the "sfg." global pointer.

Definition at line 43 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

44 {
45  sfg->pStatusSubsystem->set(sfg->pStatusSubsystem, status);
46 }
struct StatusSubsystem * pStatusSubsystem
ssSetStatus_t * set
change status immediately - no delay
Definition: status.h:50

+ Here is the caller graph for this function:

void testStatus ( SensorFusionGlobals sfg)

Definition at line 62 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

63 {
65 }
ssUpdateStatus_t * test
unit test which simply increments to next state
Definition: status.h:53
struct StatusSubsystem * pStatusSubsystem

+ Here is the caller graph for this function:

void updateStatus ( SensorFusionGlobals sfg)

Poor man's inheritance for status subsystem updateStatus command. This function is normally involved via the "sfg." global pointer.

Definition at line 57 of file sensor_fusion.c.

Referenced by initSensorFusionGlobals().

58 {
60 }
struct StatusSubsystem * pStatusSubsystem
ssUpdateStatus_t * update
make pending status active/visible
Definition: status.h:52

+ Here is the caller graph for this function:

void zeroArray ( StatusSubsystem pStatus,
void *  data,
uint16_t  size,
uint16_t  numElements,
uint8_t  check 
)
Parameters
pStatusStatus subsystem pointer
datapointer to array to be zeroed
sizedata type size = 8, 16 or 32
numElementsnumber of elements to zero out
checktrue if you would like to verify writes, false otherwise

Definition at line 320 of file sensor_fusion.c.

320  {
321  uint16_t i;
322  uint8_t *d8;
323  uint16_t *d16;
324  uint32_t *d32;
325  switch(size) {
326  case 8:
327  d8 = data;
328  for (i=0; i<numElements; i++) d8[i]=0;
329  break;
330  case 16:
331  d16 = data;
332  for (i=0; i<numElements; i++) d16[i]=0;
333  break;
334  case 32:
335  d32 = data;
336  for (i=0; i<numElements; i++) d32[i]=0;
337  break;
338  default:
339  pStatus->set(pStatus, HARD_FAULT);
340  }
341  if (check) {
342  switch(size) {
343  case 8:
344  d8 = data;
345  for (i=0; i<numElements; i++)
346  if (d8[i]!=0) pStatus->set(pStatus, HARD_FAULT);
347  break;
348  case 16:
349  d16 = data;
350  for (i=0; i<numElements; i++)
351  if (d16[i]!=0) pStatus->set(pStatus, HARD_FAULT);
352  break;
353  case 32:
354  d32 = data;
355  for (i=0; i<numElements; i++)
356  if (d32[i]!=0) pStatus->set(pStatus, HARD_FAULT);
357  break;
358  }
359  return;
360  }
361 }
Non-recoverable FAULT = something went very wrong.
ssSetStatus_t * set
change status immediately - no delay
Definition: status.h:50